package redisclient

import "fmt"
import "menteslibres.net/gosexy/redis"

const MAX_POOL_SIZE = 5

type RedisPool struct {
	host            string
	port            uint
	RedisClientPool chan *redis.Client
}

func (this *RedisPool) InitRedisClient(host string, port uint) {
	this.host = host
	this.port = port
}

func (this *RedisPool) GetRedisClient(dbno int64) *redis.Client {
	if this.RedisClientPool == nil {
		this.RedisClientPool = make(chan *redis.Client, MAX_POOL_SIZE)
	}
	if len(this.RedisClientPool) == 0 {
		go func() {
			for i := 0; i < MAX_POOL_SIZE; i++ {
				client := redis.New()
				err := client.Connect(this.host, this.port)
				if err != nil {
					fmt.Println(err)
					return
				}

				client.Select(dbno)
				this.PutRedisClient(client)
			}
		}()
	}

	client := <-this.RedisClientPool
	if _, err := client.Ping(); err != nil {
		client.Connect(this.host, this.port)
		client.Select(dbno)
	}
	client.Select(dbno)

	return client
}

func (this *RedisPool) PutRedisClient(client *redis.Client) {
	if this.RedisClientPool == nil {
		this.RedisClientPool = make(chan *redis.Client, MAX_POOL_SIZE)
	}
	if len(this.RedisClientPool) >= MAX_POOL_SIZE {
		client.Quit()
		return
	}

	this.RedisClientPool <- client
}

func (this *RedisPool) ClearRedisClient() {
	if this.RedisClientPool != nil {
		count := len(this.RedisClientPool)
		for i := 0; i < count; i++ {
			client := <-this.RedisClientPool
			client.Quit()
		}
	}
}

//重置数据有效期
func (this *RedisPool) ResetExpire(dbno int64, key *string, expire uint64) (bool, error) {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	return redisClient.Expire(*key, expire)
}

//从REDIS读数据
func (this *RedisPool) Get(dbno int64, key *string) (string, error) {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	return redisClient.Get(*key)
}

//写数据到REDIS
func (this *RedisPool) Set(dbno int64, key *string, value *string, expire uint64) bool {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	if _, err := redisClient.Set(*key, value); err != nil {
		fmt.Println(err.Error())
		return false
	}

	if expire > 0 {
		redisClient.Expire(*key, expire)
	}

	return true
}

//写数据到REDIS
func (this *RedisPool) Del(dbno int64, key *string) bool {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	if _, err := redisClient.Del(*key); err != nil {
		fmt.Println(err.Error())
		return false
	}

	return true
}

//从REDIS读数据
func (this *RedisPool) HMGet(dbno int64, table string, key string, field string) string {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	value, err := redisClient.HMGet(fmt.Sprintf("%s:%s", table, key), field)
	if err != nil {
		return ""
	}

	return value[0]
}

//写HASH数据到REDIS
func (this *RedisPool) HMSet(dbno int64, table string, key string, values ...interface{}) bool {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	//键值对形式，传值必须是：field1, value1, field2, value2
	if _, err := redisClient.HMSet(fmt.Sprintf("%s:%s", table, key), values...); err != nil {
		fmt.Println(err.Error())
		return false
	}

	return true
}

//写数据到redis list
func (this *RedisPool) LPush(dbno int64, listname string, values ...interface{}) bool {
	redisClient := this.GetRedisClient(dbno)
	defer this.PutRedisClient(redisClient)

	//键值对形式，传值必须是：field1, value1, field2, value2
	if _, err := redisClient.LPush(listname, values...); err != nil {
		fmt.Println(err.Error())
		return false
	}

	return true
}
